const crypto = require('crypto');
const uuid = require('uuid');

const SIGN_KEY = "CykdY1StU8t9EAvNQTlh613BUeLoSXgNS9EAYnKghmNcDvM8ePtisYHaWZyNE2d58GNhm8YeJ324NWW6mo3eg0QYCofezpkmCMibALwSjUJ6EmztPaekBRe3XQSoQIBi";

const buildSignParam01 = (key, timestamp, nonce) => {
    return `_key=${key}&_timestamp=${timestamp}&_nonce=${nonce}`;
};

const buildSignParam02 = (requestUri) => {
    let uri = requestUri;
    if (uri.indexOf('#') !== -1) {
        uri = uri.split('#')[0];
    }
    if (uri.indexOf('?') !== -1) {
        uri = uri.split('?')[1];
    }
    // 对参数进行排序
    const params = new URLSearchParams(uri);
    const sortedKeys = Array.from(params.keys()).sort();
    let sortedParamsString = "";
    for (const key of sortedKeys) {
        sortedParamsString += `${key}=${params.get(key)}&`;
    }
    uri = sortedParamsString.slice(0, -1);

    return decodeURIComponent(uri);
};

const buildSignParam03 = (param, method) => {
    if (!param || method !== 'post') {
        return null;
    }
    const sortedKeys = Object.keys(param).sort();
    let value = '';
    sortedKeys.forEach(key => {
        if (!param[key]) {
            value = value + key + '=' + '&';
        } else if (Array.isArray(param[key])) {
            value = value + key + '=' + param[key].join(',') + '&';
        } else {
            value = value + key + '=' + param[key].toString() + '&';
        }
    });
    if (value.endsWith('&')) {
        value = value.substring(0, value.length - 1);
    }
    return value;
};


const buildSignParam04 = () => {
    return null;
};

const buildSignParam05 = (param, method) => {
    if (!param || method !== 'post') {
        return null;
    }
    return JSON.stringify(param);
};

/**
 * 签名方法
 *
 * @param {访问地址，包含?参数，但不包含#部分, 也不包含协议域名端口} uri "/srv100352/api/pub/page/getMapConfigList?mapId=105109&types=14%2C3&t=1722162706872"
 * @param {post请求时的参数体} requestBody undefined
 * @param {亲求方法} method "get"
 * @param {密钥} key SIGN_KEY
 * @param {时间偏差} d 996
 */
const signature = (uri, requestBody = undefined, method = 'get', key = SIGN_KEY, d = 996) => {
    let timestamp = new Date().getTime();
    let nonce = uuid.v4().replace(/-/g, '');

    let result = {
        nonce: nonce,
        timestamp: timestamp + d,
        signature: ''
    };

    let p1 = buildSignParam01(key, result.timestamp, nonce);

    let p2 = buildSignParam02(uri);

    let p3 = buildSignParam03(requestBody, method);

    let p4 = buildSignParam04();

    let p5 = buildSignParam05(requestBody, method);

    let str = [p1, p2, p3, p4, p5].map(it => {
        return it != null ? it : ''
    }).join(',');
    result.signature = crypto.createHash('md5').update(str).digest('hex').slice(0, 32).toUpperCase();

    console.log('signature', result, str);

    return result;
};

module.exports = signature;